#pragma once

#pragma warning( push, 0 )	// Ignore external library warnings...
#pragma warning( disable : 4244 )
#pragma warning( disable : 4267 )
#pragma warning( disable : 4512 )
#pragma warning( disable : 4996 )
#pragma warning( disable : 6001 )
#pragma warning( disable : 6011 )
#pragma warning( disable : 6282 )
#pragma warning( disable : 6326 )
#pragma warning( disable : 6334 )

// Windows/System
#define NOMINMAX
#include <process.h>  // _beginthread, _endthread
#include <winsock2.h>
#ifdef _DEBUG
	#include <Crtdbg.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>

// Don't hide stl min/max.
#ifdef max
	#undef max
#endif
#ifdef min
	#undef min
#endif

// Std lib
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <list>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <limits>
#include <stdexcept>

// Boost
//#define BOOST_ALL_NO_LIB
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <boost/static_assert.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/tracking.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>

// Quantum Framework
#include <QPCpp/qep_port.h>  // Quantum framework - defines sized types and includes windows.h

#pragma warning( pop ) 

#ifdef _DEBUG
	#define ASSERT_THROW_MSG(condition, message) \
		if (!(condition)) \
		{ \
			std::stringstream msg; \
			msg << __FILE__ << '(' << __LINE__ << ") " << (message); \
			int i = ::MessageBoxA(0, (msg.str() + "\r\nPress Abort to throw, Retry to break, Ignore to continue.").c_str(), "Debug Assertion", MB_ABORTRETRYIGNORE); \
			switch (i) \
			{ \
			case IDRETRY: \
				::DebugBreak(); \
				break; \
			case IDIGNORE: \
				break; \
			case IDABORT: \
			default: \
				throw std::exception(msg.str().c_str()); \
			} \
		}
#else
	#define ASSERT_THROW_MSG(condition, message) \
		if (!(condition)) \
		{ \
			std::stringstream msg; \
			msg << __FILE__ << '(' << __LINE__ << ") " << (message); \
			throw std::exception(msg.str().c_str()); \
		}
#endif

#define ASSERT_THROW(condition) ASSERT_THROW_MSG((condition), #condition)

#ifndef ASSERT
	#ifdef _DEBUG
		#define ASSERT(f) ASSERT_THROW(f)
	#else
		#define ASSERT(f)
	#endif
#endif

#ifndef ASSERT_MSG
	#ifdef _DEBUG
		#define ASSERT_MSG(f, m) ASSERT_THROW_MSG(f, m)
	#else
		#define ASSERT_MSG(f, m)
	#endif
#endif

#ifndef VERIFY
	#ifdef _DEBUG
		#define VERIFY(f) ASSERT(f)
	#else
		#define VERIFY(f) ((void)(f))
	#endif
#endif

#ifndef VERIFY_MSG
	#ifdef _DEBUG
		#define VERIFY_MSG(f, m) ASSERT(f, m)
	#else
		#define VERIFY_MSG(f, m) ((void)(f))
	#endif
#endif

// WG14/N843 C99 Standard, Section 7.18.2.1  Limits of exact-width integer types
#ifndef INT8_MIN
	#define INT8_MIN    (-0x7f - 1)
#endif
#ifndef INT16_MIN
	#define INT16_MIN   (-0x7fff - 1)
#endif
#ifndef INT32_MIN
	#define INT32_MIN   (-0x7fffffff - 1)
#endif

#ifndef INT8_MAX
	#define INT8_MAX    0x7f
#endif
#ifndef INT16_MAX
	#define INT16_MAX   0x7fff
#endif
#ifndef INT32_MAX
	#define INT32_MAX   0x7fffffff
#endif

#ifndef UINT8_MAX
	#define UINT8_MAX   0xff
#endif
#ifndef UINT16_MAX
	#define UINT16_MAX  0xffff
#endif
#ifndef UINT32_MAX
	#define UINT32_MAX  0xffffffff
#endif

#pragma comment(lib, "qep.lib")
#pragma comment(lib, "WS2_32.LIB")

// Preprocessor macros for creating a *clickable* user-defined #pragma message(...)
// NOTE:  The placement of the spaces around the colon here is crucial!
//        See the MSDN article at [http://support.microsoft.com/kb/155196].
// Usage: #pragma message(__HERE__ "Your custom warning message...")
#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#define __HERE__ __FILE__ "("__STR1__(__LINE__)") : "

